﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.Net.Mail;
using Confcloud.Core.Architecture;
using Smarly.Core.Database;

namespace Confcloud.Email
{
	public partial class EmailQueue : RestObject<Confcloud.Email.EmailQueue>
	{
		public int EmailQueueId { get; set; }
		public SmtpSetting Smtp { get; set; }
		public string Recipient { get; set; }
		public string BccRecipient { get; set; }
		public string Subject { get; set; }
		public string Body { get; set; }
		public bool IsHtml { get; set; }
		internal Guid SmtpSettingId { get; set; }

		internal string ErrorText { get; set; }

		public class SmtpSetting
		{
			internal Guid SmtpSettingId { get; set; }
			internal string Server { get; set; }
			internal string Login { get; set; }
			internal string Password { get; set; }
			internal int Port { get; set; }
			internal bool IsSsl { get; set; }

			internal SmtpClient SmtpClient
			{
				get
				{
					return new SmtpClient("smtp.yandex.ru")
					       	{
					       		Credentials = new System.Net.NetworkCredential(/*Login*/"smarly@smarly.net", /*Password*/"Odissey1980"),
					       	};
/*
					return new SmtpClient
					       	{
					       		Host = "smtp.yandex.ru"/*Server#1#,
					       		Port = /*Port#1#465,
										Credentials = new NetworkCredential(/*Login#1#"smarly@smarly.net", /*Password#1#"Odissey1980"),
					       		//DeliveryMethod = SmtpDeliveryMethod.Network,
					       		EnableSsl = /*IsSsl#1#true,
										UseDefaultCredentials = false,
					       	};
*/
				}
			}
		}

		#region Overrides of RestObject<EmailQueue>

		public override Confcloud.Email.EmailQueue Get()
		{
			throw new NotImplementedException();
		}

		public override Confcloud.Email.EmailQueue Post()
		{
			throw new NotImplementedException();
		}

		public override Confcloud.Email.EmailQueue Put()
		{
				var sqlParams = new List<SpParam>
				                	{
				                		new SpParam {Name = "@emailQueueId", Type = DbType.Int32, Value = EmailQueueId},
				                		new SpParam {Name = "@errorText", Type = DbType.String, Value = ErrorText},
				                	};
				return SqlRepository.ExecuteProcedureReader("[dbo].[EmailQueue_Put]", sqlParams, OnSqlInfoMessage, (reader) => this);
		}

		public override Confcloud.Email.EmailQueue Delete()
		{
			throw new NotImplementedException();
		}

		#endregion

	}

	public partial class EmailQueue<T> : RestObject<T> where T : class
	{
		internal EmailQueue()
		{
		}


		protected EmailQueue(string templateName)
		{
			TemplateName = templateName;
		}

		protected string TemplateName;

		protected string Recipent { get; set; }
		protected string BccRecipent { get; set; }


		#region Parameters

		public const string PlatformName = "PLATFORMNAME";
		public const string Email = "EMAIL";
		public const string Solutation = "SOLUTATION";
		public const string FirstName = "FIRSTNAME";
		public const string LastName = "LASTNAME";
		public const string MiddleName = "MIDDLENAME";

		#endregion


		protected string Data { get; set; }

		protected const string DataParamDelimiter = "###";
		protected const string DataPairParamDelimiter = "##";

		protected void AddParam(string key, string value)
		{
			Data = Data ?? string.Empty;

			if (!Data.EndsWith(DataParamDelimiter))
				Data += DataParamDelimiter;

			Data += key + DataPairParamDelimiter + value + DataParamDelimiter;
		}

		#region Overrides of RestObject<T>

		public override T Get()
		{
				var sqlParams = new List<SpParam>
				                	{
				                		new SpParam {Name = "@timeout", Type = DbType.Int32, Value = EmailSender.EmailTimeOut},
				                	};
				return SqlRepository.ExecuteProcedureReader("[dbo].[EmailQueue_Get]", sqlParams, OnSqlInfoMessage, EmailQueueReadEmailsOnSend);
		}

		private DateTime? _beginSendDate = null;
		public DateTime BeginSendDate { set { _beginSendDate = value; } get { return _beginSendDate.HasValue ? _beginSendDate.Value : DateTime.Now; } }

		public override T Post()
		{
				var sqlParams = new List<SpParam>
				                	{
				                		new SpParam {Name = "@templateName", Type = DbType.String, Value = TemplateName},
				                		new SpParam {Name = "@beginSentDate", Type = DbType.String, Value = BeginSendDate},

				                		new SpParam {Name = "@recipient", Type = DbType.String, Value = Recipent},
				                		new SpParam {Name = "@bccRecipient", Type = DbType.String, Value = BccRecipent},

				                		new SpParam {Name = "@parameters", Type = DbType.String, Value = Data ?? string.Empty},

				                		new SpParam {Name = "@parameterDelimiter", Type = DbType.String, Value = DataParamDelimiter},
				                		new SpParam {Name = "@pairDelimiter", Type = DbType.String, Value = DataPairParamDelimiter},
				                	};


				return SqlRepository.ExecuteProcedureReader("[dbo].[EmailQueue_Post]", sqlParams, OnSqlInfoMessage, (reader) =>
				                                                                                   	{
				                                                                                   		while (reader.Read())
																																																EmailSender.SetTimerDate(reader.GetDateTimeOrNull("BeginSentDate"));

				                                                                                   		return this;
				                                                                                   	}) as T;

		}

		private T EmailQueueReadEmailsOnSend(IDataReader reader)
		{
			int batchNum = 0;
			EmailQueue<T> result = this;
			do
			{
				switch (batchNum)
				{
					case 0:
						result.EmailsOnSend = ListMapping(reader, ReadEmailQueue);
						break;
					case 1:
						DateTime? beginDate = null;
						while (reader.Read())
						{
							beginDate = reader.GetDateTimeOrNull("BeginSentDate");
						}
						EmailSender.SetTimerDate(beginDate);
						break;
				}
				batchNum++;
			} while (reader.NextResult());

			return result as T;
		}


		private static Confcloud.Email.EmailQueue ReadEmailQueue(IDataReader reader)
		{
			return new Confcloud.Email.EmailQueue
			{
				EmailQueueId = reader.GetInt32("EmailQueueId"),
				Recipient = reader.GetString("Recipient"),
				BccRecipient = reader.GetStringOrNull("BccRecipient"),
				Subject = reader.GetString("Subject"),
				Body = reader.GetString("Body"),
				IsHtml = reader.GetBoolean("IsHtml"),
				Smtp = new EmailQueue.SmtpSetting(),
			};
		}


		public override T Put()
		{
			throw new NotImplementedException();
		}

		public override T Delete()
		{
			throw new NotImplementedException();
		}

		#endregion

		#region Timer

		private List<Confcloud.Email.EmailQueue> EmailsOnSend { get; set; }

		public static List<Confcloud.Email.EmailQueue> ReadEmails
		{
			get
			{
				var emailQueue = new EmailQueue<object>();
				emailQueue.Get();
				return emailQueue.EmailsOnSend;
			}
		}
		//public static DateTime? CloserSendDate { get; set; }



		#endregion

	}
}